const express = require('express')
const route = express.Router()
const User = require('../../models/User')
const bcrypt = require('bcrypt')
const jwt = require('jsonwebtoken')
const SALT = 'wenliang'
const Article = require('../../models/Article')
const Design = require('../../models/Design')
const Category = require('../../models/Category')
const Comment = require('../../models/Comment')
const multer = require('multer')
const { RSA_PKCS1_OAEP_PADDING } = require('constants')
const upload = multer({
    dest: __dirname + '/../../upload'
})

module.exports = (app) => {
    // 注册接口
    route.post('/register', async (req, res) => {
        // 判断用户名是否存在
        const conflict = await User.find({
            username : req.body.username
        })
        if(conflict.length){
            res.send({
                message: "× 用户名已存在"
            })
            return
        }

        // 用户名不存在, 可以注册
        let password = bcrypt.hashSync(req.body.password, 10)
        const result = await User.create({
            username: req.body.username,
            password: password
        })
        if(result){
            const token = jwt.sign({
                _id: String(result._id)
            }, SALT)
            res.send({message: '注册成功', token: 'Bearer ' + token})
        }
    })
    // 登录接口
    route.post('/login', async (req, res) => {
        const result = await User.find({username: req.body.username}).select('password')
        if(!result.length){
            res.send({message: "用户名或密码错误"})
        }else{
            if(bcrypt.compareSync(req.body.password, result[0].password)){
                const token = jwt.sign({
                    _id: String(result[0]._id)
                }, SALT)
                res.send({message: '登录成功', token: 'Bearer ' + token})
            }else{
                res.send({message: '用户名或密码错误'})
            }
        }
    })
    // 拉取todolist 接口
    route.get('/todolist', async (req, res) => {
        if(req.userId){
            const result = await User.findById(req.userId).lean()
            res.send(result)
        }else{
            res.send({message: '请先登录'})
        }
    })
    // todolist 更新接口
    route.post('/todolist', async(req, res) => {
        if(!req.userId){
            res.send({message: '请先登录！'})
        }
        await User.findByIdAndUpdate(req.userId, req.body).lean()
        const result = await User.findById(req.userId)
        res.send(result)
    })

    //  获取用户自定义的导航
    route.get('/navlist', async (req, res) => {
        const result = await User.findById(req.userId)
        res.send(result)
    })
    //  更新用户自定义的导航
    route.post('/navlist', async (req, res) => {
        await User.findByIdAndUpdate(req.userId, {navList: req.body})
        const result = await User.findById(req.userId)
        res.send(result)
    })

    //  获取用户信息接口
    route.get('/user', async (req, res) => {
        const result = await User.findById(req.userId).lean()
        res.send(result)
    })

    // 更新用户默认搜索引擎
    route.post('/searchEngine', async(req, res) => {
        if(req.userId){
            await User.findByIdAndUpdate(req.userId, req.body)
            res.send({message: 'success'})
        }
    })

    // 获取学习笔记列表接口
    route.get('/notepad', async (req, res) => {
        let result = await Article.find().populate('categories').populate("userId").lean()
        result = result.filter(item => {
            if(!item.userId){return true}
            if(item.userId.username == "wenliang" || item.userId.username == "admin"){ return true}
        })
        res.send(result)
    })

    // 添加文章接口
    route.post('/addArticle', async (req, res) => {
        const model = await Article.create(req.body)
    })

    // 编辑更新文章
    route.post('/articleUpdate/:id', async (req, res) => {
        const result = await Article.findByIdAndUpdate(req.params.id, req.body)
        res.send(result)
    })

    //  删除文章
    route.delete('/deleteArticle/:id', async (req, res) => {
        const result = await Article.findByIdAndRemove(req.params.id)
        await Comment.deleteMany({ articleId: req.params.id})
        res.send({message: 'success', status: 200})
    })


    // 添加设计作品接口
    route.post('/addDesign', async (req, res) => {
        const model = await Design.create(req.body)
        res.send({message: 'success', status: 200})
    })

    route.put('/addDesign/:id', async (req, res) => {
        const result = await Design.findByIdAndUpdate(req.params.id, req.body)
        res.send({status: 200, message: 'success'})
    })

    route.delete('/deleteDesign/:id', async (req, res) => {
        const result = await Design.findByIdAndRemove(req.params.id)
        await Comment.deleteMany({ articleId: req.params.id})
        res.send({message: 'success', status: 200})
    })

    //  删除评论
    route.delete('/removeComment/:artId/:comId', async (req, res) => {
        if(await Design.findById(req.params.artId)){
            let model = await Design.findById(req.params.artId)
            comment = model.comment
            let index = comment.indexOf(req.params.comId)
            comment.splice(index, 1)
            await Design.findByIdAndUpdate(req.params.artId, {comment: comment})
        }else{
            let model = await Article.findById(req.params.artId)
            comment = model.comment
            let index = comment.indexOf(req.params.comId)
            comment.splice(index, 1)
            await Article.findByIdAndUpdate(req.params.artId, {comment: comment})
        }
        await Comment.findByIdAndDelete(req.params.comId)

        res.send({status: 200, message:'success'})
    })

    //  删除评论中的回复
    route.delete('/removeReply/:comId/:repId', async (req, res) => {
        const model = await Comment.findById(req.params.comId).lean()
        let index = model.comment.findIndex(value => value._id == req.params.repId)
        model.comment.splice(index, 1)
        await Comment.findByIdAndUpdate(req.params.comId, {comment: model.comment})
        res.send({status: 200, message: 'success'})
    })

    //  获取账户自己的文章、收藏、关注用户文章列表
    route.get('/rest/myArticleList/:userId/:sort', async (req, res) => {
        let result = []
        const articles = await Article.find().populate('userId categories comment').lean()
        const user = await User.findById(req.params.userId)
        if(req.params.sort == '我的文章'){
            result = articles.filter(item =>{
                if(item.userId && item.userId._id){
                    return item.userId._id == req.params.userId
                }
                return false
            })
        }else if(req.params.sort == '我的收藏'){
            let collectArr = user.collectArticle
            result = articles.filter(item => collectArr.indexOf(item._id) > -1)
        }else if(req.params.sort == '关注文章'){
            let attention = user.attention
            result = articles.filter(item => attention.indexOf(item.userId ? item.userId._id : '') > -1)
        }
        addCount(result)
        res.send(result)
    })

    //  获取账户自己的设计、收藏、关注用户设计列表
    route.get('/rest/myDesignList/:userId/:sort', async (req, res) => {
        let result = {status: 200, message:'请求不到相应的数据'}
        const articles = await Design.find().populate('comment').populate('userId').lean()
        if(req.params.sort == '我的设计'){
            result = articles.filter(item => item.userId._id == req.params.userId)
        }else if(req.params.sort == '设计收藏'){
            const userInfo = await User.findById(req.params.userId).populate('collectDesign').populate('collectDesign.userId').lean()
            result = userInfo.collectDesign
        }else if(req.params.sort == '关注设计'){
            const user = await User.findById(req.params.userId)
            const attention = user.attention
            result = articles.filter(item => attention.indexOf(item.userId ? item.userId : '') > -1)
        }
        addCount(result)
        res.send(result)
    })

    //  获取可用头像
    route.get('/rest/touxiang', async (req, res) => {
        const fs = require('fs')
        const path = require('path')
        const dirname = path.resolve(__dirname, '../../images/touxiang/')
        let result = await fs.promises.readdir(dirname)
        result = result.map(item => `https://www.sunwenliang.com/images/touxiang/${item}`)
        res.send(result)
    })

    //  用户更换头像
    route.post('/changeTouxiang/:id', async (req, res) => {
        await User.findByIdAndUpdate(req.params.id, req.body)
        res.send({status: 200, message: 'success'})
    })

    //  新增、取消关注用户
    route.get('/guanzhu/:type/:userId/:attentionId', async (req, res) => {
        const user = await User.findById(req.params.userId).lean()
        if(req.params.type == 'add'){
            user.attention = user.attention ? user.attention : []
            user.attention.indexOf(req.params.attentionId) > -1 || user.attention.unshift(req.params.attentionId)
        }else{
            let index = user.attention.indexOf(req.params.attentionId)
            user.attention.splice(index, 1)
        }
        const result = await User.findByIdAndUpdate(req.params.userId, {attention: user.attention})
        if(result){
            res.send({status: 200, message: 'success'})
        }
    })

    //  收藏、取消收藏文章、设计
    route.get('/collect/:model/:type/:userId/:collectId', async (req, res) => {
        const Model = require(`../../models/${req.params.model}`)
        const user = await User.findById(req.params.userId).lean()
        if(req.params.type == 'add'){
            user[`collect${req.params.model}`] = user[`collect${req.params.model}`] ? user[`collect${req.params.model}`] : []
            user[`collect${req.params.model}`].indexOf(req.params.collectId) > -1 || user[`collect${req.params.model}`].unshift(req.params.collectId)
        }else{
            let index = user[`collect${req.params.model}`].indexOf(req.params.collectId)
            user[`collect${req.params.model}`].splice(index, 1)
        }
        const result = await User.findByIdAndUpdate(req.params.userId, {[`collect${req.params.model}`]: user[`collect${req.params.model}`]})
        if(result){
            res.send({status: 200, message: 'success'})
        }
    })

    app.use('/client/api', auth, route)


    // 判断用户登录是否过期
    function auth(req, res, next){
        const token = req.headers.authorization && req.headers.authorization.split(' ')[1]
        if(token){
            try {
                // 用户正常登录添加req.userId， 后面根据req.userId是否存在判断是否登录
                const result = jwt.verify(token, SALT)
                req.userId = result._id
            } catch (error) {
                return res.send({message: '请重新登录'})
            }
        }
        next()
    }

    //  获取文章分类列表
    app.get('/client/api/rest/Category', async (req, res) => {
        const model = await Category.find().lean()
        res.send(model)
    })

    //  为文章和设计稿添加评论数量
    function addCount(data){
        if(!data.length){return}
        data.map(item => {
            let count = 0
            for(let i = 0; i < (item.comment ? item.comment.length : 0); i++){
                count ++
                for(let j = 0; j < (item.comment[i].comment ? item.comment[i].comment.length : 0); j ++){
                count ++
                }
            }
            item.commentsCount = count
        }) 
    }

    //  获取公开文章列表
    app.get('/client/api/rest/articleList/:page', async(req, res) => {
        let model = await Article.find().populate('userId').populate('categories').populate('comment').lean()
        model = model.filter(item => item.publicOr && item.publicOr == true)
        model = model.reverse()
        addCount(model)
        model.count = model.length
        res.send(model.splice(req.params.page * 10, 10))
    })

    //  获取公开设计列表
    app.get('/client/api/rest/designList/:page', async(req, res) => {
        let model = await Design.find().populate('userId').populate('comment').lean()
        model = model.filter(item => item.publicOr && item.publicOr == true)
        model = model.map(item => {
            delete item.content
            return item
        }).reverse()
        model.count = model.length
        res.send(model.splice(req.params.page * 30, 30))
    })
    //  获取文章详细信息
    app.get('/client/api/rest/:model/:id', async (req, res) => {
        const Model = require(`../../models/${req.params.model}`)
        let model = await Model.findById(req.params.id).populate('userId categories')
        model.views = model.views ? ++ model.views : 1
        await Model.findByIdAndUpdate(req.params.id, {views: model.views})
        model.comment && (model.comment = await Promise.all(model.comment.map(item => Comment.findById(item)
        .populate('commentUserId').populate('comment.responseUserId comment.responseWhoId'))))
        res.send(model)
    })

    //  上传图片
    app.post('/client/api/image/upload', upload.single('file'), (req, res) => {
        const file = req.file
        file.url = `https://www.sunwenliang.com/upload/${req.file.filename}`
        res.send(file)
    })
    
    //  发表评论
    app.post('/client/api/publishComment/:artId', async (req, res) => {
        // 添加评论数据
        let result = await Comment.create(Object.assign(req.body, {
            articleId: req.params.artId,
            publishTime: new Date().getTime()
        }))
        // 找到被评论的文章，添加评论数据_id到文章的comment数组中
        let Model
        if(await Design.findById(req.params.artId)){ Model = Design }else{ Model = Article }
        let model = await Model.findById(req.params.artId).lean()
        model.comment = model.comment ? model.comment : []
        model.comment.unshift(result._id) 
        result = await Model.findByIdAndUpdate(req.params.artId, {comment: model.comment}).lean()

        // 遍历所有的评论信息，包装成一个数组到文章对象里面
        // result.comment = model.comment.map(async (item) => await Comment.findById(item))
        result.comment = await Promise.all(model.comment.map(item => Comment.findById(item)
        .populate('commentUserId').populate('comment.responseUserId comment.responseWhoId')))
        res.send(result)
    })
    
    //  回复评论
    app.post('/client/api/reply2pinglun/:comId', async (req, res) => {
        const comment = await Comment.findById(req.params.comId).lean()
        comment.comment.push(Object.assign({}, req.body, {replyTime: new Date().getTime()}))
        const result = await Comment.findByIdAndUpdate(req.params.comId, {comment:comment.comment})
        res.send(result)
    })

    //  获取论坛文章数量，回复数量，用户数量
    app.get('/client/api/count', async (req, res) => {
        let obj = {users:0, articles:0, comments:0}
        const articles = await Article.find()
        obj.users = (await User.find()).length
        obj.articles = articles.length
        const comment = await Comment.find()
        comment.map(item => {
            obj.comments++
            item.comment.map(i => obj.comments++)
        })
        function sortCount(id){
            let count = 0
            articles.map(item => {
                if(item.categories.indexOf(id) != -1){
                    count ++
                }
            })
            return count
        }
        obj.JavaScript = sortCount('5fc1e9237091aa0f8885e659')
        obj.design = sortCount('5fc1ec1d7091aa0f8885e65d')
        obj.ES6 = sortCount('5ff4447bfa3b662f90e07248')
        obj.VUE = sortCount('5ff44481fa3b662f90e07249')
        obj.MongoDB = sortCount('5ff444b7fa3b662f90e0724a')
        obj.MySql = sortCount('5ff444befa3b662f90e0724b')
        obj.NodeJS = sortCount('5ff444c8fa3b662f90e0724c')
        res.send(obj)
    })

    //  获取文章子分类通用接口
    app.get('/client/api/articleSort/:sort', async (req, res) => {
        let model = await Article.find().populate('userId').populate('categories').lean()
        model = model.filter(item => item.publicOr && item.publicOr == true)
        if(req.params.sort == 'all'){
            model = model.map(item => {
                delete item.content
                return item
            })
        }else{
            model = model.filter(item => {
                delete item.content
                return item.categories.filter(item => item._id == req.params.sort).length
            })
        }
        res.send(model.reverse())
    })
    // Article.updateMany({}, {$set:{comment:[]}}).then(console.log(1))
    // Design.updateMany({}, {$set:{comment:[]}}).then(console.log(1))

    //  文章点赞接口
    app.get('/client/api/dianzan/:model/:sort/:artId/:userId', async (req, res) => {
        let Model = require(`../../models/${req.params.model}`)
        let article = await Model.findById(req.params.artId).lean()
        if(req.params.sort == 'add'){
            article.like = article.like ? article.like : []
            article.like.push(req.params.userId)
            await Model.findByIdAndUpdate(req.params.artId, {like: article.like})
        }else{
            console.log(typeof JSON.parse(JSON.stringify(article.like))[0], typeof req.params.userId)
            console.log(JSON.parse(JSON.stringify(article.like))[0], req.params.userId)
            const index = (JSON.parse(JSON.stringify(article.like))).indexOf(req.params.userId)
            article.like.splice(index, 1)
            await Model.findByIdAndUpdate(req.params.artId, {like: article.like})
        }
        res.send({status: 200, message: 'success'})
    })
    //  点赞评论
    app.get('/client/api/dzcomment/:add/:comId/:userId', async (req, res) => {
        const comment = await Comment.findById(req.params.comId)
        if(req.params.add == 'add'){
            comment.like.push(req.params.userId)
            await Comment.findByIdAndUpdate(req.params.comId, {like: comment.like})
        }else{
            const index = comment.like.indexOf(req.params.userId)
            comment.like.splice(index, 1)
            await Comment.findByIdAndUpdate(req.params.comId, {like: comment.like})
        }
        res.send({status: 200, message: 'success'})
    })
    //  点赞评论中的回复
    app.get('/client/api/dzreply/:add/:comId/:replyId/:userId', async (req, res) => {
        const comment = await Comment.findById(req.params.comId)
        if(req.params.add == 'add'){
            comment.comment[req.params.replyId].like.push(req.params.userId)
            await Comment.findByIdAndUpdate(req.params.comId, {comment: comment.comment})
        }else{
            const index = comment.comment[req.params.replyId].like.indexOf(req.params.userId)
            comment.comment[req.params.replyId].like.splice(index, 1)
            await Comment.findByIdAndUpdate(req.params.comId, {comment: comment.comment})
        }
        res.send({status: 200, message: 'success'})
    })

    //  站内搜索
    app.post('/client/api/search/:model', async (req, res) => {
        let model = await Article.find().populate('userId').populate('categories').populate('comment').lean()
        const result = model.filter(item => {
            delete item.content
            let flag = false
            for(let i = 0; i < req.body.length; i++){
                item.title.toLowerCase().indexOf(req.body[i].toLowerCase()) > -1 && (flag = true)                
            }
            return flag
        })
        res.send(result)
    })

}